﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Xml.Linq;
using System.Xml.Serialization;

namespace MultitouchApplication
{
    public class RssReader : UserControl, INotifyPropertyChanged
    {
        public RssReader()
        {
            StackPanel sp = new StackPanel();
            sp.Background = new SolidColorBrush(Colors.Red);
            TextBlock tb = new TextBlock();
            tb.Text = "[ RSS READER ]";
            sp.Children.Add(tb);
            this.Content = sp;

            this.Loaded += (s, e) =>
                {
                    if (AutoLoad)
                    {
                        Load();
                    }
                };
        }

        #region Properties

        public bool AutoLoad
        {
            get { return (bool)GetValue(AutoLoadProperty); }
            set { SetValue(AutoLoadProperty, value); }
        }

        public static readonly DependencyProperty AutoLoadProperty =
            DependencyProperty.Register("AutoLoad", typeof(bool), typeof(RssReader), new PropertyMetadata(true));

        public int UpdateIntervalInMinutes
        {
            get { return (int)GetValue(UpdateIntervalInMinutesProperty); }
            set { SetValue(UpdateIntervalInMinutesProperty, value); }
        }

        public static readonly DependencyProperty UpdateIntervalInMinutesProperty =
            DependencyProperty.Register("UpdateIntervalInMinutes", typeof(int), typeof(RssReader), new PropertyMetadata(5));

        public int MaxItemsInStore
        {
            get { return (int)GetValue(MaxItemsInStoreProperty); }
            set { SetValue(MaxItemsInStoreProperty, value); }
        }

        public static readonly DependencyProperty MaxItemsInStoreProperty =
            DependencyProperty.Register("MaxItemsInStore", typeof(int), typeof(RssReader), new PropertyMetadata(100));

        public bool CacheItemsInIsolatedStore
        {
            get { return (bool)GetValue(CacheItemsInIsolatedStoreProperty); }
            set { SetValue(CacheItemsInIsolatedStoreProperty, value); }
        }

        public static readonly DependencyProperty CacheItemsInIsolatedStoreProperty =
            DependencyProperty.Register("CacheItemsInIsolatedStore", typeof(bool), typeof(RssReader), new PropertyMetadata(true));

        public string SourceUrl 
        {
            get { return (string)GetValue(SourceUrlProperty); }
            set { SetValue(SourceUrlProperty, value); }
        }

        public static readonly DependencyProperty SourceUrlProperty =
            DependencyProperty.Register("SourceUrl ", typeof(string), typeof(RssReader), new PropertyMetadata("http://sport.msn.de/rss/news/aktuell"));

        FeedItem[] _feedItems;
        public FeedItem[] FeedItems
        {
            get
            {
                return _feedItems;
            }
            set
            {
                _feedItems = value;
                OnPropertyChanged("FeedItems");
            }
        }

        #endregion

        #region IPropertyNotifyChanged

        private void OnPropertyChanged(string propertyname)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyname));
            }
        }
        public event PropertyChangedEventHandler PropertyChanged;

        #endregion

        #region Public Methods

        public void Load()
        {
            WebClient webclient = new WebClient();
            webclient.DownloadStringCompleted += (s, e) =>
                {
                    if (e.Error != null)
                    {
                        OnError(e.Error);
                    }
                    else
                    {
                        OnLoaded(e.Result);
                    }
                };
            Uri uri = new Uri(SourceUrl);
            webclient.DownloadStringAsync(uri);
        }

        #endregion

        private void OnLoaded(string text)
        {
            XElement xmlNews = XElement.Parse(text);

            List<FeedItem> result = new List<FeedItem>();
            foreach (var item in xmlNews.Descendants("item"))
            {
                FeedItem rssItem = new FeedItem();
                rssItem.Guid = GetValueAsString(item, "guid");
                rssItem.Title = GetValueAsString(item, "title");
                rssItem.Content = GetValueAsString(item, "description");
                rssItem.Link = GetValueAsString(item, "link");
                
                string timeString = GetValueAsString(item, "pubDate");
                DateTime time = DateTime.Parse(timeString);
                rssItem.DateTime = time;
                
                if (item.Element("enclosure") != null)
                {
                    rssItem.Media = item.Element("enclosure").Attribute("url").Value;
                }
                result.Add(rssItem);
            }

            this.FeedItems = result.ToArray();
        }

        private string GetValueAsString(XElement item, string name)
        {
            if (item.Element(name) != null)
            {
                return (string)item.Element(name).Value;
            }
            else
            {
                return string.Empty;
            }
        }

        private void OnError(Exception exception)
        {
            if (Error != null)
            {
                Error(this, new ErrorArgs() { Exception = exception });
            }
        }

        public event EventHandler<ErrorArgs> Error;
    }

    public class Feed : INotifyPropertyChanged
    {
        public string Title { get; set; }
        private List<FeedItem> _items;

        public Feed()
        {
            _items = new List<FeedItem>();
        }

        public FeedItem[] Items
        {
            get 
            {
                var result = from i in _items
                             orderby i.DateTime
                             select i;
                return result.ToArray(); 
            }
        }

        private void SaveToCache()
        {
            string filename = this.Title + ".xml";
            using (var file = System.IO.IsolatedStorage.IsolatedStorageFile.GetUserStoreForApplication().CreateFile(filename))
            {
                XmlSerializer xs = new XmlSerializer(typeof(Feed));
                xs.Serialize(file, this);
                file.Close();
            }
        }

        private void LoadFromCache()
        {
            string filename = this.Title + ".xml";
            using (var file = System.IO.IsolatedStorage.IsolatedStorageFile.GetUserStoreForApplication().OpenFile(filename, System.IO.FileMode.Open))
            {
                XmlSerializer xs = new XmlSerializer(typeof(Feed));
                Feed feed = (Feed)xs.Deserialize(file);
                file.Close();
            }
        }

        private void AddItem(List<FeedItem> items)
        {
            foreach (var item in items)
            {
                // Download Image
                string filename = item.Media;
                if (filename != string.Empty)
                {

                }

                // Set new image url

                // Add to list
                _items.Add(item);
            }
        }

        #region IPropertyNotifyChanged

        private void OnPropertyChanged(string propertyname)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyname));
            }
        }
        public event PropertyChangedEventHandler PropertyChanged;

        #endregion

    }

    public class FeedItem
    {
        public string Title { get; set; }
        public DateTime DateTime { get; set; }
        public string Content { get; set; }
        public string Media { get; set; }
        public string Link { get; set; }
        public string Guid { get; set; }

        public static FeedItem[] GetSampleData()
        {
            List<FeedItem> result = new List<FeedItem>();
#if DEBUG
            for (int i=0;i<30;i++)
            {
                FeedItem fi = new FeedItem();
                fi.Title = "Title " + i.ToString();
                fi.Link = "http://www.website.com";
                fi.Content = "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.";
                fi.Media = "http://www.apicture.com/picture.jpg";
                fi.DateTime = DateTime.Now;
                result.Add(fi);
            }
#endif
            return result.ToArray();

        }
    }

    public class ErrorArgs : EventArgs
    {
        public Exception Exception { get; set; }
    }
}
